﻿using IdentityServer.Data.Repositories;
using IdentityServer.Models;
using IdentityServer4.Models;
using IdentityServer4.Validation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using WeChatIdentity.Constants;
using WeChatIdentity.Models;

namespace IdentityServer.Validator
{
    /// <summary>
    /// 自定义微信校验
    /// </summary>
    public class WeiXinOpenGrantValidator : IExtensionGrantValidator
    {
        private readonly IUserRepository _repository;
        public WeiXinOpenGrantValidator(IUserRepository repository)
        {
            _repository = repository;
        }
        public string GrantType => GrantTypeConstants.ResourceWeixinOpen;

        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            try
            {
                //参数获取,授权
                var openId = context.Request.Raw[ParamConstants.OpenId];
                var userName = context.Request.Raw[ParamConstants.UserName];
                var country = context.Request.Raw[ParamConstants.Country];
                var province = context.Request.Raw[ParamConstants.Province];
                var city = context.Request.Raw[ParamConstants.City];
                var gender = context.Request.Raw[ParamConstants.Gender];
                var avatarUrl = context.Request.Raw[ParamConstants.AvatarUrl];

                if (string.IsNullOrEmpty(openId))
                {
                    context.Result = new GrantValidationResult(
                    TokenRequestErrors.InvalidGrant,
                    "授权失败,sub为空"
                    );
                }
               //通过openId和unionId 参数来进行数据库的相关验证
                var claimList = await ValidateUserAsync(openId, userName,country,province,city,gender,avatarUrl);
                //授权通过返回
                if (claimList.Any())
                {
                    context.Result = new GrantValidationResult
                    (
                        subject: claimList.Where(t => t.Type == ClaimTypes.Name).FirstOrDefault().Value,
                        authenticationMethod: "custom",
                        claims: claimList.ToArray()
                    );
                }
                else
                {
                    context.Result = new GrantValidationResult(
                    TokenRequestErrors.InvalidGrant,
                    "授权失败"
                    );
                }
            }
            catch (Exception ex)
            {
                context.Result = new GrantValidationResult()
                {
                    IsError = true,
                    Error = $"WeiXinOpenGrantValidator Error:{ex.Message}"
                };
            }
        }

        /// <summary>
        /// 验证用户
        /// </summary>
        /// <param name="subjectId"></param>
        /// <param name="openId"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        private async Task<List<Claim>> ValidateUserAsync(string openId,string userName,string country,string province,string city,string gender,string avatarUrl)
        {
            var user = await _repository.GetUserByOpenIdAsync(openId);
            if (user == null)
            {
               await _repository.AddUserAsync(new ApplicationUser(userName, openId, userName,avatarUrl,gender,province,city,country));
            }
            return new List<Claim>()
            {
                new Claim(ClaimTypes.Name, $"{user.SubjectId}"),
            };
        }
    }
}
